// 观察者模式
// 优缺点：观察者模式好处是能够降低耦合，目标对象和观察者对象逻辑互不干扰，两者都专注于自身的功能，只提供和调用了更新接口；而缺点也很明显，在目标对象中维护的所有观察者都能接收到通知，无法进行过滤筛选

/**
 * 发布订阅与观察者的区别
 * 发布/订阅模式中，发布者并不维护订阅者，也不知道订阅者的存在，所以也不会直接通知订阅者，而是通知调度中心，由调度中心通知订阅者
 * 观察者模式把观察者对象维护在目标对象中的，需要发布消息时直接发消息给观察者。在观察者模式中，目标对象本身是知道观察者存在的
 * https://zhuanlan.zhihu.com/p/357911263
 * https://xieyufei.com/2020/12/16/DefineProperty-Proxy.html
 */

// 观察者
class Observer {
  constructor(cb, payload) {
    this.cb = cb;
    this.payload = payload;
  }
  update() {
    this.cb(this.payload);
  }
}
// 目标对象，收集观察者
class Subject {
  constructor() {
    this.observers = [];
  }
  add(observer) {
    this.observers.push(observer);
  }
  remove(observer) {
    this.observers = this.observers.filter((obs) => obs !== observer);
  }
  notify() {
    this.observers.forEach((observer) => observer.update());
  }
}

// 测试
const test1 = (payload) => console.log("test1-----" + payload);
const test2 = (payload) => console.log("test2======" + payload);
const test3 = (payload) => console.log("test3]]]]]]" + payload);
const subject = new Subject();
const observer1 = new Observer(test1, "123");
const observer2 = new Observer(test2, "456");
const observer3 = new Observer(test3, "789");
subject.add(observer1);
subject.add(observer2);
subject.add(observer3);
subject.notify();
subject.remove(observer3);
subject.notify();
